Package-level declarations

Extensions of built-in types (e.g. Either, Option, etc)

Types

Link copied to clipboard
typealias ErrorOr<T> = Either<Throwable, T>
Link copied to clipboard
object Nullable
Link copied to clipboard
typealias OutcomeOf<A> = Outcome<Throwable, A>

Functions

Link copied to clipboard
fun <E, A> Either<E, A>.asOption(): Option<A>

Turns your Either into an Option.

Link copied to clipboard
fun <E, A> ValidatedNel<E, A>.attemptValidated(): Either<Throwable, A>

Turns your Validated List into an Either, but will throw an exception in the Left hand case.

Link copied to clipboard
inline fun <ERR, A, B> ValidatedNel<ERR, A>.concatMap(f: (A) -> ValidatedNel<ERR, B>): ValidatedNel<ERR, B>

The Validated type doesn't natively support flatMap because of the monad laws that it breaks. But this is what flatMap would do if it were allowed. We've called it concatMap because the Kotlin compiler will want to wire in the Monad flatMap extension instead and confusion reigns.

Link copied to clipboard
fun <A> List<Option<A>>.filterNotNone(): List<A>

Returns a list without Nones

Link copied to clipboard
inline fun <A, B, C> Either<A, B>.flatTap(f: (B) -> Either<A, C>): Either<A, B>

Performs an effect over the right side of the value but maps the original value back into the Either. This is useful for mixing with validation functions.

Link copied to clipboard
inline fun <A, B> Either<A, B>.forEach(f: (B) -> Unit)

Performs an effect on the right side of the Either.

inline fun <A> Option<A>.forEach(f: (A) -> Unit)

Runs a side effect if the option is a Some

Link copied to clipboard
fun <K, A> Map<K, A>.getOption(k: K): Option<A>

Extension function to get an Option from a nullable object on a map.

Link copied to clipboard
inline fun <T> Option<T>.ifAbsent(f: () -> Unit)

Takes a function to run if your Option is None. Returns Unit if your Option is Some.

Link copied to clipboard
inline fun <A> Option<A>.ifPresent(f: (A) -> Unit)

Runs a side effect if the option is a Some. Same as forEach, just a different name for better symmetry with ifAbsent.

Link copied to clipboard
fun <E, A> Either<E, A>.leftAsOption(): Option<E>

Turns the left side of your Either into an Option.

Link copied to clipboard
inline fun <A, B> Either<A, B>.leftForEach(f: (A) -> Unit)

Performs an effect on the left side of the Either.

Link copied to clipboard
fun <A> listOfSome(vararg elements: Option<A>): List<A>

Constructs a flattened list without Nones

Link copied to clipboard
fun <A, B> suspend () -> A.map(f: (A) -> B): suspend () -> B

Map on this suspended supplier with a suspended function.

fun <A, B, C> suspend (A) -> B.map(f: (B) -> C): suspend (A) -> C

Map on this suspended function with another.

Link copied to clipboard
inline fun <A, B> Nel<A>.mapNotNone(f: (A) -> Option<B>): Option<Nel<B>>

Applies a function that produces an Option to a NonEmptyList. The result is None if the resulting list would be empty, otherwise Some(NonEmptyList).

inline fun <A, B> List<A>.mapNotNone(f: (A) -> Option<B>): List<B>

Returns a list containing only the non-None results of applying the given transform function to each element in the original collection.

Link copied to clipboard
inline fun <E, T, V> Either<E, Option<T>>.mapOption(f: (T) -> V): Either<E, Option<V>>

Map on a nested Either Option type.

Link copied to clipboard
inline fun <E, A> Either<E, A>.or(f: () -> Either<E, A>): Either<E, A>

Returns the first successful either, otherwise the last failure

infix fun <T> Option<T>.or(other: Option<T>): Option<T>
infix fun <T> Option<T>.or(other: () -> Option<T>): Option<T>

Returns this if it's a Some, otherwise returns the other instance

Link copied to clipboard
fun <T> Option<T>.orEmpty(f: (T) -> String): String

Will return an empty string if the Optional value supplied is None

Link copied to clipboard
fun <A> Either<Throwable, A>.orThrow(): A

Retrieves the Right hand of an Either, or throws the Left hand error

Link copied to clipboard
fun <E, A> Either<E, Option<A>>.sequence(): Option<Either<E, A>>
fun <E, A> Either<E, Iterable<A>>.sequence(): List<Either<E, A>>
Link copied to clipboard
fun <ERR, A> ValidatedNel<ERR, A>.takeLeft(other: ValidatedNel<ERR, A>): ValidatedNel<ERR, A>

Often you have two validations that return the same thing, and you don't want necessarily to pair them. takeLeft will return the value of the left side iff both validations succeed.

Link copied to clipboard
fun <ERR, A> ValidatedNel<ERR, A>.takeRight(other: ValidatedNel<ERR, A>): ValidatedNel<ERR, A>

Often you have two validations that return the same thing, and you don't want necessarily to pair them. takeRight will return the value of the right side iff both validations succeed.

Link copied to clipboard
inline fun <A, B> Either<A, B>.tapLeft(f: (A) -> Unit): Either<A, B>

Pass the left value to the function (e.g. for logging errors)

Link copied to clipboard
fun <T> Result<T>.toEither(): ErrorOr<T>

Transforms a Result<T> into an ErrorOr<T>

inline fun <A, B> B?.toEither(left: () -> A): Either<A, B>

Lifts a nullable value into an Either, similar to toOption. Must supply the left side of the Either.

Link copied to clipboard
inline fun <T, E> Option<T>.toValidatedNel(error: () -> E): ValidatedNel<E, T>

Turns your Option into a Validated list of T if it's a Some. If it's a None, will return a Nel of the error function passed in

Link copied to clipboard
inline fun <E, A, B> Either<E, A>.traverse(transform: (value: A) -> Option<B>): Option<Either<E, B>>
inline fun <E, A, B> Either<E, A>.traverse(transform: (value: A) -> Iterable<B>): List<Either<E, B>>

inline fun <E, A, B> Nel<A>.traverse(f: (A) -> Either<E, B>): Either<E, NonEmptyList<B>>

Map a function that returns an Either across the NonEmptyList.

inline fun <A, B> NonEmptyList<A>.traverse(f: (A) -> Option<B>): Option<NonEmptyList<B>>

Map a function that returns an Option across the NonEmptyList.

inline fun <T, E, U> Option<T>.traverse(f: (T) -> Either<E, U>): Either<E, Option<U>>

Map a function that returns an Either across the Option.

inline fun <A, B> Option<A>.traverse(f: (A) -> Iterable<B>): List<Option<B>>

Map a function that returns an Iterable across the Option.

inline fun <E, A, B> Iterable<A>.traverse(f: (A) -> Either<E, B>): Either<E, List<B>>

Returns an Either of a list of B results of applying the given transform function to each element(A) in the original collection.

inline fun <A, B> Iterable<A>.traverse(f: (A) -> Option<B>): Option<List<B>>

Returns an Option of a list of B results of applying the given transform function to each element(A) in the original collection.

Link copied to clipboard
inline fun <E, A, B> Nel<A>.traverseEither(f: (A) -> Either<E, B>): Either<E, NonEmptyList<B>>

Synonym for traverse((A)-> Either): Either>

inline fun <T, E, U> Option<T>.traverseEither(f: (T) -> Either<E, U>): Either<E, Option<U>>

Synonym for traverse((T)-> Either): Either>

inline fun <E, A, B> Iterable<A>.traverseEither(f: (A) -> Either<E, B>): Either<E, List<B>>

Synonym for traverse((A)-> Either): Either>

Link copied to clipboard
inline fun <E, A, B> Either<E, A>.traverseOption(transform: (A) -> Option<B>): Option<Either<E, B>>

Synonym for traverse((A)-> Option): Option>

inline fun <A, B> NonEmptyList<A>.traverseOption(f: (A) -> Option<B>): Option<NonEmptyList<B>>

Synonym for traverse((A)-> Option): Option>

inline fun <A, B> Iterable<A>.traverseOption(f: (A) -> Option<B>): Option<List<B>>

Synonym for traverse((A)-> Option): Option>

Link copied to clipboard
fun <A, B> Either<A, B>.unit(): Either<A, Unit>

Map right to Unit. This restores .void() which was deprecated by Arrow.

fun <A> Option<A>.unit(): Option<Unit>

Map some to Unit. This restores .void() which was deprecated by Arrow.

Link copied to clipboard
inline fun <ERR, A> A.validate(predicate: (A) -> Boolean, error: (A) -> ERR): ValidatedNel<ERR, A>

Given a predicate and an error generating function return either the original value in a ValidNel if the predicate evaluates as true or the generated error in an InvalidNel.

Link copied to clipboard
inline fun <ERR, A> A.validateEither(predicate: (A) -> Boolean, error: (A) -> ERR): Either<ERR, A>

Given a predicate and an error generating function return either the original value in a Right if the predicate evaluates as true or the error as a Left.

Link copied to clipboard
inline fun <ERR, A, B> A.validateMap(f: (A) -> Either<Throwable, B>, error: (A, Throwable) -> ERR): ValidatedNel<ERR, B>

Given a mapping function and an error message, return either the result of the function in a ValidNel if the function completes successfully, or the error message in an InvalidNel.

Link copied to clipboard
fun <B> B?.validateNotNull(label: Option<String> = None): Either<Throwable, B>

Turns a nullable value into an Either. This is useful for building validation functions.

Link copied to clipboard
suspend fun <T> suspend () -> ErrorOr<T>.withRetries(until: (ErrorOr<T>) -> Boolean = { it.isRight() }, additionalTimes: Int = 4, delay: Duration = Duration.ofMillis(20L), exponentialBackoff: Boolean = false, jitter: Boolean = false): ErrorOr<T>

Retry a suspended supplier of an ErrorOr until a maximum number of times or a predicate has been fulfilled.

Link copied to clipboard
suspend fun <T> suspend () -> T.withRetriesOrThrow(until: (ErrorOr<T>) -> Boolean = { it.isRight() }, additionalTimes: Int = 4, delay: Duration = Duration.ofMillis(20L), exponentialBackoff: Boolean = false, jitter: Boolean = false): ErrorOr<T>

Retry a suspended supplier until a maximum number of times or a predicate has been fulfilled.

Link copied to clipboard
inline fun <A, B, C, D> Either<A, B>.zip(b: Either<A, C>, transform: (B, C) -> D): Either<A, D>
inline fun <A, B, C, D, E> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, transform: (B, C, D) -> E): Either<A, E>
inline fun <A, B, C, D> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, map: (B, C) -> D): Ior<A, D>
inline fun <A, B, C, D, E, F> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, transform: (B, C, D, E) -> F): Either<A, F>
inline fun <A, B, C, D, E> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, map: (B, C, D) -> E): Ior<A, E>
inline fun <A, B, C, D, E, F, G> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, transform: (B, C, D, E, F) -> G): Either<A, G>
inline fun <A, B, C, D, E, F> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, map: (B, C, D, E) -> F): Ior<A, F>
inline fun <A, B, C, D, E, F, G, H> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, f: Either<A, G>, transform: (B, C, D, E, F, G) -> H): Either<A, H>
inline fun <A, B, C, D, E, F, G> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, map: (B, C, D, E, F) -> G): Ior<A, G>
inline fun <A, B, C, D, E, F, G, H, I> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, f: Either<A, G>, g: Either<A, H>, transform: (B, C, D, E, F, G, H) -> I): Either<A, I>
inline fun <A, B, C, D, E, F, G, H> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, g: Ior<A, G>, map: (B, C, D, E, F, G) -> H): Ior<A, H>
inline fun <A, B, C, D, E, F, G, H, I, J> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, f: Either<A, G>, g: Either<A, H>, h: Either<A, I>, transform: (B, C, D, E, F, G, H, I) -> J): Either<A, J>
inline fun <A, B, C, D, E, F, G, H, I> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, g: Ior<A, G>, h: Ior<A, H>, map: (B, C, D, E, F, G, H) -> I): Ior<A, I>
inline fun <A, B, C, D, E, F, G, H, I, J, K> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, f: Either<A, G>, g: Either<A, H>, h: Either<A, I>, i: Either<A, J>, transform: (B, C, D, E, F, G, H, I, J) -> K): Either<A, K>
inline fun <A, B, C, D, E, F, G, H, I, J> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, g: Ior<A, G>, h: Ior<A, H>, i: Ior<A, I>, map: (B, C, D, E, F, G, H, I) -> J): Ior<A, J>
inline fun <A, B, C, D, E, F, G, H, I, J, K, L> Either<A, B>.zip(b: Either<A, C>, c: Either<A, D>, d: Either<A, E>, e: Either<A, F>, f: Either<A, G>, g: Either<A, H>, h: Either<A, I>, i: Either<A, J>, j: Either<A, K>, transform: (B, C, D, E, F, G, H, I, J, K) -> L): Either<A, L>
inline fun <A, B, C, D, E, F, G, H, I, J, K> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, g: Ior<A, G>, h: Ior<A, H>, i: Ior<A, I>, j: Ior<A, J>, map: (B, C, D, E, F, G, H, I, J) -> K): Ior<A, K>
inline fun <A, B, C, D, E, F, G, H, I, J, K, L> Ior<A, B>.zip(crossinline combine: (A, A) -> A, c: Ior<A, C>, d: Ior<A, D>, e: Ior<A, E>, f: Ior<A, F>, g: Ior<A, G>, h: Ior<A, H>, i: Ior<A, I>, j: Ior<A, J>, k: Ior<A, K>, transform: (B, C, D, E, F, G, H, I, J, K) -> L): Ior<A, L>